package utilities;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public class JSONArchiver implements Archiver {
	// Instance Variables
	private String filename;
	
	
	// Constructor
	/**
	 * Constructor: takes in a filename to save/load data
	 */
	public JSONArchiver(String filename) {
		this.filename = filename;
	}
	
	
	// Methods
	/**
	 * This method creates an Archive, creates a Generator to generate the JSON,
	 * and writes the JSON string out to the filename
	 */
	public void save(Archiveable object) {
		// Get the object's Archive
		Archive archive = object.save();
		
		// Generate the JSON string
		Generator generator = new JSONGenerator();
		String json = generator.generate(archive);
		
		System.out.println("generated JSON: " + json);
		
		// Save the JSON string to file
		this.writeToFile(json);
	}
	
	/**
	 * This method loads the JSON string from the filename, creates a Parser to
	 * parse it into an Archive, and passes it to the object
	 */
	public void load(Archiveable object) {
		// Read the json string from file
		String json = this.readFromFile();
		
		// Parse json
		Parser parser = new JSONParser(json);
		Archive archive = parser.parse();
		
		// Call load
		object.load(archive);
	}
	
	
	// File IO
	/**
	 * This method reads a string from filename
	 */
	private String readFromFile() {
		String data = "";
		try {
			File file = new File(this.filename);
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
			String line = null;
			while ((line = br.readLine()) != null) {
				data += line;
			}
			br.close();
		} catch (Exception ex) {
			return null;
		}
		return data;
	}
	
	/**
	 * This method saves the string to filename
	 */
	private void writeToFile(String string) {
		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(this.filename));
			writer.write(string);
		} catch (IOException e) {
			
		} finally {
			try {
				if (writer != null)
					writer.close();
			} catch (IOException e) {
				
			}
		}
	}
	
}
